package com.Java.train.business.service.daily.Impl;

import cn.hutool.core.date.DateUtil;
import com.Java.train.business.entity.*;
import com.Java.train.business.entity.DTO.TrainCarriageDTO;
import com.Java.train.business.enums.SeatTypeEnum;
import com.Java.train.business.service.TrainSeatService;
import com.Java.train.business.service.TrainStationService;
import com.Java.train.common.response.CommonResp;
import com.Java.train.business.entity.DTO.DailyTrainSeatDTO;
import com.Java.train.business.req.daily.DailyTrainSeatQueryReq;
import com.Java.train.common.exception.BusniessException;
import com.Java.train.common.exception.BusniessExceptionEnum;
import com.Java.train.common.response.PageResp;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.Java.train.business.mapper.DailyTrainSeatMapper;
import com.Java.train.business.service.daily.DailyTrainSeatService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import com.Java.train.common.context.LoginMemberContext;
import com.Java.train.common.utils.SnowFlakeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import org.springframework.util.CollectionUtils;
import cn.hutool.core.date.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
* 每日座位 服务实现类
*
* @author luomoxingchen
* @since 2024-09-24
*/
@Service
public class DailyTrainSeatServiceImpl extends ServiceImpl<DailyTrainSeatMapper, DailyTrainSeat> implements DailyTrainSeatService {

    private static final Logger LOG = LoggerFactory.getLogger(DailyTrainSeatService.class);

    @Autowired
    DailyTrainSeatMapper dailyTrainSeatMapper;

    @Resource
    TrainSeatService trainSeatService;
    @Resource
    TrainStationService trainStationService;

    @Override
    public PageResp<DailyTrainSeatDTO> queryList(DailyTrainSeatQueryReq dailyTrainSeatQueryReq){
        // 1.获取当前用户id信息
        //        Long id = LoginMemberContext.getId();
        String trainCode = dailyTrainSeatQueryReq.getCode();
        // 2.查询数据库中是否存在当前信息（id）
        LOG.info("查询页码：{}", dailyTrainSeatQueryReq.getPage());
        LOG.info("每页条数：{}", dailyTrainSeatQueryReq.getSize());
        PageHelper.startPage(dailyTrainSeatQueryReq.getPage(),dailyTrainSeatQueryReq.getSize());

        // 筛选
        List<DailyTrainSeat> dailyTrainSeats = null;
        if(StrUtil.isNotBlank(trainCode)){
            dailyTrainSeats = getDailySeatByCondition(trainCode);
        }else {
            dailyTrainSeats = list();
        }

        if(dailyTrainSeats == null || CollUtil.isEmpty(dailyTrainSeats)){
            // 返回空列表
            return new PageResp<DailyTrainSeatDTO>();
//            throw new BusniessException(BusniessExceptionEnum.MEMBER_PASSENGER_NOT_EXITS);
        }

        // 3 分析分页信息
        // 3.1 获取分页总条数和页数
        PageInfo<DailyTrainSeat> pageInfo = new PageInfo<>(dailyTrainSeats);
        LOG.info("总行数：{}", pageInfo.getTotal());
        LOG.info("总页数：{}", pageInfo.getPages());

        // 3.2 转为封装后的返回值并封装到分页返回值中
        List<DailyTrainSeatDTO> list = BeanUtil.copyToList(dailyTrainSeats, DailyTrainSeatDTO.class);
        PageResp<DailyTrainSeatDTO> pageResp = new PageResp<>();
        pageResp.setTotal(pageInfo.getTotal());
        pageResp.setList(list);
        // 4.返回查询到的信息
        return pageResp;
    }

    @Override
    public CommonResp<Object> modify(DailyTrainSeat dailyTrainSeat) {
        Long id = dailyTrainSeat.getId();
        DateTime dateTime = DateTime.now();
        if(ObjectUtil.isNull(id)){
            dailyTrainSeat.setId(SnowFlakeUtil.getSnowFlakeNextId());
            dailyTrainSeat.setCreateTime(dateTime);
            dailyTrainSeat.setUpdateTime(dateTime);
            boolean save = save(dailyTrainSeat);
            return new CommonResp<>(save);
        } else {
            dailyTrainSeat.setUpdateTime(dateTime);
            boolean update = updateById(dailyTrainSeat);
            return new CommonResp<>(update);
        }
    }

    @Override
    public CommonResp<Object> remove(String ids) {
        if(StrUtil.isNotEmpty(ids)){
            String[] array = ids.split(",");
            if(!CollectionUtils.isEmpty(Arrays.asList(array))) {
                return new CommonResp<>(dailyTrainSeatMapper.deleteBatchIds(Arrays.asList(array)));
            }
        }
        return new CommonResp<>(Collections.EMPTY_LIST);
    }

    @Override
    public void getDaily(Date date, String trainCode) {
        LOG.info("生成日期为[{}]车次编号为[{}]的车座数据开始", DateUtil.formatDate(date), trainCode);
        // 1.查询是否存在火车
//        LambdaQueryWrapper<TrainSeat> wrapper = new LambdaQueryWrapper<>();
//        List<TrainSeat> seats = trainSeatService.list(wrapper.eq(TrainSeat::getTrainCode, trainCode)
//                .orderBy(true, true, TrainSeat::getCarriageIndex, TrainSeat::getCarriageSeatIndex));
//        if(CollUtil.isEmpty(seats)) {
//            LOG.info("没有火车车厢信息");
////            throw new BusniessException(BusniessExceptionEnum.BUSINESS_TRAINSTATION_NOT_EXITS);
//        }

        // 2.复制生成dailyTrain

//        List<DailyTrainSeat> dailyTrainSeats = BeanUtil.copyToList(seats, DailyTrainSeat.class);
//         2.1 删除之前生成的火车车厢(直接删一个车厢）
        long s1 = System.currentTimeMillis();
        LambdaQueryWrapper<DailyTrainSeat> dailyWrapper = new LambdaQueryWrapper<>();
        remove(dailyWrapper.eq(DailyTrainSeat::getTrainCode, trainCode).eq(DailyTrainSeat::getDate, date));
        long e1 = System.currentTimeMillis();
        LOG.info("删除车厢耗时为：{}", e1 - s1);
//
//        // 2.2 查询当前车座信息
//        LambdaQueryWrapper<TrainSeat> wrapper = new LambdaQueryWrapper<>();
//        List<TrainSeat> seats = trainSeatService.list(wrapper.eq(TrainSeat::getTrainCode, trainCode));
//        if(CollUtil.isEmpty(seats)) {
//            LOG.info("没有火车车厢信息");
//            return;
//        }
//
//        List<DailyTrainSeat> dailyTrainSeats = BeanUtil.copyToList(seats, DailyTrainSeat.class);
//        // 2.2 获取车站站数，生成基本售卖情况sell
//        LambdaQueryWrapper<TrainStation> trainStationWrapper = new LambdaQueryWrapper<>();
//        long count = trainStationService.count(trainStationWrapper.eq(TrainStation::getTrainCode, trainCode));
//        String sell = StrUtil.fillBefore("", '0', (int) count - 1);
//
//        DateTime dateTime = DateTime.now();
//        for (DailyTrainSeat dailyTrainSeat : dailyTrainSeats) {
//            // 2.3 生成每日车厢
//            dailyTrainSeat.setSell(sell);
//            dailyTrainSeat.setId(SnowFlakeUtil.getSnowFlakeNextId());
//            dailyTrainSeat.setCreateTime(dateTime);
//            dailyTrainSeat.setUpdateTime(dateTime);
//            dailyTrainSeat.setDate(date);
//            save(dailyTrainSeat);
//        }

        // 查经过多少站点
        long s2 = System.currentTimeMillis();
        LambdaQueryWrapper<TrainStation> trainStationWrapper = new LambdaQueryWrapper<>();
        long count = trainStationService.count(trainStationWrapper.eq(TrainStation::getTrainCode, trainCode));
        String sell = StrUtil.fillBefore("", '0', (int) count - 1);
        long e2 = System.currentTimeMillis();
        LOG.info("初始化车站sell耗时为：{}", e2 - s2);

        // 查出某车次的所有的座位信息
        long s3 = System.currentTimeMillis();
        LambdaQueryWrapper<TrainSeat> wrapper = new LambdaQueryWrapper<>();
        List<TrainSeat> seatList = trainSeatService.list(wrapper.eq(TrainSeat::getTrainCode, trainCode));
        if (CollUtil.isEmpty(seatList)) {
            LOG.info("该车次没有座位基础数据，生成该车次的座位信息结束");
            return;
        }
        long e3 = System.currentTimeMillis();
        LOG.info("查询车次所有车座信息耗时为：{}", e3 - s3);

        long s4 = System.currentTimeMillis();
        LOG.info("生成座位总数为：{}",seatList.size());
        // 在数组统一存储之前耗时为：6552， 改为一次存储后的耗时为：3482 , 在mysql配置后添加rewriteBatchedStatements=true后的速度为：163
        List<DailyTrainSeat> list = new ArrayList<>();
        for (TrainSeat trainSeat : seatList) {
            DateTime now = DateTime.now();
            DailyTrainSeat dailyTrainSeat = BeanUtil.copyProperties(trainSeat, DailyTrainSeat.class);
            dailyTrainSeat.setId(SnowFlakeUtil.getSnowFlakeNextId());
            dailyTrainSeat.setCreateTime(now);
            dailyTrainSeat.setUpdateTime(now);
            dailyTrainSeat.setDate(date);
            dailyTrainSeat.setSell(sell);
            list.add(dailyTrainSeat);
//            dailyTrainSeatMapper.insert(dailyTrainSeat);
        }
        saveBatch(list);
        long e4 = System.currentTimeMillis();
        LOG.info("生成每日座位耗时为：{}", e4 - s4);
        LOG.info("生成日期【{}】车次【{}】的座位信息结束", DateUtil.formatDate(date), trainCode);
        LOG.info("生成日期为[{}]车次编号为[{}]的车座数据结束", DateUtil.formatDate(date), trainCode);
    }

    @Override
    public int countTypeSeat(Date date, String trainCode, String type) {
        LambdaQueryWrapper<DailyTrainSeat> seatWrapper = new LambdaQueryWrapper<>();
        long ZW = count(seatWrapper.eq(DailyTrainSeat::getDate,date).eq(DailyTrainSeat::getTrainCode, trainCode).eq(DailyTrainSeat::getSeatType, type));
        if(ZW == 0){
            ZW = -1;
        }
        return (int) ZW;
    }

     /**
      * @Description: 按车厢号筛选车座
      * @param
      * @return
      */
    @Override
    public List<DailyTrainSeat> selectByCarriageIdx(Date date, String trainCode, Integer trainCarriageIdx) {
        LambdaQueryWrapper<DailyTrainSeat> wrapper = new LambdaQueryWrapper<>();
        List<DailyTrainSeat> list = list(wrapper.eq(DailyTrainSeat::getDate, date).eq(DailyTrainSeat::getTrainCode, trainCode)
                .eq(DailyTrainSeat::getCarriageIndex, trainCarriageIdx));
        return list;
    }

    // 筛选条件
    private List<DailyTrainSeat> getDailySeatByCondition(String trainCode) {
        LambdaQueryWrapper<DailyTrainSeat> wrapper = new LambdaQueryWrapper<>();
        List<DailyTrainSeat> dailyTrainSeats = list(wrapper.eq(DailyTrainSeat::getTrainCode, trainCode)
                .orderBy(true, true, DailyTrainSeat::getTrainCode)
                .orderBy(true, true, DailyTrainSeat::getCarriageIndex)
                .orderBy(true, true, DailyTrainSeat::getCarriageSeatIndex));
        return dailyTrainSeats;
    }


}


